<?php
// +----------------------------------------------------------------------
// | Author: 真夜 <446107014@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\service;

class Rsa2Service
{
	const PRIVATE_KEY  = '';//rsa_private_key.pem 内容
	const PUBLIC_KEY = '';//rsa_public_key.pem 内容
	
	/**
	 * 获取私钥
	 * @return bool|resource
	 */
	private static function getPrivateKey($privKey = null)
	{
		if(empty($privKey)){
			$privKey = self::PRIVATE_KEY;
		}
		
		if(!self::checkEmpty($privKey)){
			//读字符串
			$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
					wordwrap($privKey, 64, "\n", true) .
					"\n-----END RSA PRIVATE KEY-----";
			return $res;
		}
		return null;
	}
	
	/**
	 * 获取公钥
	 * @return bool|resource
	 */
	private static function getPublicKey($publicKey = null)
	{
		if(empty($publicKey)){
			$publicKey = self::PUBLIC_KEY;
		}
		if(!self::checkEmpty($publicKey)){
			
			$res = "-----BEGIN PUBLIC KEY-----\n" .
					wordwrap($publicKey, 64, "\n", true) .
					"\n-----END PUBLIC KEY-----";
			return $res;
		}
		return null;
	}
	
	/**
	 * 校验$value是否非空
	 *  if not set ,return true;
	 *    if is null , return true;
	 **/
	private static function checkEmpty($value) {
		
		if (!isset($value))
			return true;
		if ($value === null)
			return true;
		if (trim($value) === "")
			return true;
					
		return false;
	}
	
	private static function getSignContent($params) {
		ksort($params);
		
		$stringToBeSigned = "";
		$i = 0;
		foreach ($params as $k => $v) {
			if (false === self::checkEmpty($v) && "@" != substr($v, 0, 1)) {
				
				if ($i == 0) {
					$stringToBeSigned .= "$k" . "=" . "$v";
				} else {
					$stringToBeSigned .= "&" . "$k" . "=" . "$v";
				}
				$i++;
			}
		}
		
		unset ($k, $v);
		return $stringToBeSigned;
	}
	
	/**
	 * 创建签名
	 * @param string $data 数据
	 * @return null|string
	 */
	public static function createSign($data = [],$privKey = null)
	{
		if(empty($data)){
			return null;
		}
		$str = self::getSignContent($data);
		$privateKey = self::getPrivateKey($privKey);
		if(empty($privateKey)){
			return null;
		}
		
		return openssl_sign(
				$str,
				$sign,
				$privateKey,
				OPENSSL_ALGO_SHA256
				) ? base64_encode($sign) : null;
	}
	
	/**
	 * 验证签名
	 * @param string $data 数据
	 * @param string $sign 签名
	 * @return bool
	 */
	public static function verifySign($data = [],$pubKey = null)
	{
		if(empty($data)){
			return false;
		}
		$sign = $data['sign'];
		if(empty($sign)){
			return false;
		}
		else{
			unset($data['sign']);
		}
		$str = self::getSignContent($data);
		$publicKey = self::getPublicKey($pubKey);
		if(empty($publicKey)){
			return false;
		}
		return (bool)openssl_verify(
				$str,
				base64_decode($sign),
				$publicKey,
				OPENSSL_ALGO_SHA256
				);
	}
}